package com.sdy.healthcode.biz.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethodBase;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;

import java.io.UnsupportedEncodingException;
import java.util.Map;

import static org.springframework.util.StringUtils.isEmpty;

/**
 * <p>
 * 发起http请求
 * </p>
 *
 * @author fb
 * @since 2019/11/4
 */
@Slf4j
public class HttpReqUtil {

    /**
     * 创建get请求
     * @param url 接口地址
     * @param respCharset 返回字符集编码
     * @return
     */
    public static String get(String url, String respCharset, Integer timeout, Map<String,String> header){
        HttpClient client = new HttpClient();
        // 设置超时时间
        client.setConnectionTimeout(timeout);
        client.setTimeout(timeout);
        GetMethod get = new GetMethod(url);
        String response;
        // 一般网络原因引起的异常设置不重试请求
        get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));
        try {
            setHeader(get, header);
            client.executeMethod(get);
            response = IOUtils.toString(get.getResponseBodyAsStream(), respCharset);
        } catch (Exception e) {
            log.error("", e);
            throw new RuntimeException(e);
        } finally {
            get.releaseConnection();
        }
        return response;
    }

    /**
     * 创建post请求
     * @param client HttpClient
     * @param post post请求
     * @param respCharset 返回字符集编码
     * @return
     */
    private static String req(HttpClient client, PostMethod post, String respCharset, Integer overTime,
                              Map<String,String> map){
        String response = "";
        // 一般网络原因引起的异常设置不重试请求
        post.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(0,false));
        try {
            // 发送请求
            setHeader(post,map);
            client.executeMethod(post);
            response = IOUtils.toString(post.getResponseBodyAsStream(), respCharset);
        } catch (Exception e) {
            log.error("", e);
            throw new RuntimeException(e);
        } finally {
            post.releaseConnection();
        }
        return response;
    }

    /**
     * 发起form请求
     * @param url 接口地址
     * @param parts
     * @param reqCharset 请求字符集编码
     * @param respCharset 返回字符集编码
     * @return
     */
    public static String postMultipart(String url, Part[] parts, String reqCharset, String respCharset,
                                       Integer overTime, Map<String,String> map){
        HttpClient client = new HttpClient();
        client.setConnectionTimeout(overTime);
        client.setTimeout(overTime);
        PostMethod post = new PostMethod(url);
        post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, reqCharset);
        if(parts != null){
            post.setRequestEntity(new MultipartRequestEntity(parts, post.getParams()));
        }
        return req(client, post, respCharset, overTime, map);
    }

    /**
     * 发起json请求
     * @param url 接口地址
     * @param jsonStr
     * @param reqCharset 请求字符集编码
     * @param respCharset 返回字符集编码
     * @return
     * @throws Exception
     */
    public static String postJson(String url, String jsonStr, String reqCharset, String respCharset, Integer overTime,
                                  Map<String,String> map) {
        HttpClient client = new HttpClient();
        client.setConnectionTimeout(overTime);
        client.setTimeout(overTime);
        PostMethod post = new PostMethod(url);
        post.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, reqCharset);
        try {
            post.setRequestEntity(new StringRequestEntity(jsonStr,"application/json", reqCharset));
        } catch (UnsupportedEncodingException e) {
            log.error("", e);
            throw new RuntimeException(e);
        }
        return req(client, post, respCharset, overTime, map);
    }

    /**
     * 发起urlencoded请求
     * @param url 接口地址
     * @param param
     * @param reqCharset 请求字符集编码
     * @param respCharset 返回字符集编码
     * @return
     */
    public static String postUrlencoded(String url, NameValuePair[] param,  String reqCharset, String respCharset,
                                        Integer overTime, Map<String,String> map) {
        HttpClient client = new HttpClient();
        client.setConnectionTimeout(overTime);
        client.setTimeout(overTime);
        PostMethod post = new PostMethod(url);
        post.getParams().setContentCharset(reqCharset);
        post.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset="+reqCharset);
        post.addParameters(param);
        return req(client, post, respCharset, overTime, map);
    }

    /**
     * 设置请求头信息
     * @param method
     * @param map
     */
    private static void setHeader(HttpMethodBase method, Map<String,String> map){
        if(!isEmpty(map)) {
            if(map.size() != 0){
                for(Map.Entry<String, String> entry : map.entrySet()) {
                    method.setRequestHeader(entry.getKey(), entry.getValue());
                }
            }
        }
    }

}
